home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / mtrace.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  4KB  |  147 lines

  1. /* More debugging hooks for `malloc'.
  2.    Copyright 1991 Free Software Foundation
  3.           Written April 2, 1991 by John Gilmore of Cygnus Support
  4.           Based on mcheck.c by Mike Haertel.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdio.h>
  21. #include "ansidecl.h"
  22.  
  23. /* size_t may be defined in the system-supplied stdio.h.  */
  24. /* So just kludge it.  */
  25. #define size_t unsigned int
  26. #define ptrdiff_t int
  27. #define __ONEFILE
  28.  
  29. /* We can't declare malloc and realloc here because we don't know
  30.    if they are char * or void *, and the compiler will give an error
  31.    if we get it wrong and they happen to be defined in some header
  32.    file e.g. <stdio.h>.  We can't include <stdlib.h> here because
  33.    it has some incompatability with our own includes, e.g. size_t or 
  34.    whatever.  So we just punt.  This causes malloc and realloc to
  35.    default to returning "int", which works for most cases we care
  36.    about.  FIXME-somehow.  */
  37. /* #include <stdlib.h> */
  38. #include "gmalloc.h"
  39.  
  40. extern char *getenv();
  41.  
  42. FILE *mallstream;
  43. char mallenv[] = "MALLOC_TRACE";
  44. static char mallbuf[BUFSIZ];        /* Buffer for the output */
  45.  
  46. /* Address to breakpoint on accesses to... */
  47. PTR mallwatch;
  48.  
  49. /* Old hook values.  */
  50. static void EXFUN((*old_free_hook), (PTR ptr));
  51. static PTR EXFUN((*old_malloc_hook), (size_t size));
  52. static PTR EXFUN((*old_realloc_hook), (PTR ptr, size_t size));
  53.  
  54. /* This function is called when the block being alloc'd, realloc'd, or
  55.    freed has an address matching the variable "mallwatch".  In a debugger,
  56.    set "mallwatch" to the address of interest, then put a breakpoint on
  57.    tr_break.  */
  58.  
  59. void
  60. tr_break()
  61. {
  62.   ;
  63. }
  64.  
  65. static void
  66. DEFUN(tr_freehook, (ptr), PTR ptr)
  67. {
  68.   fprintf(mallstream, "- %08x\n", ptr);    /* Be sure to print it first */
  69.   if (ptr == mallwatch)
  70.     tr_break();
  71.   __free_hook = old_free_hook;
  72.   free(ptr);
  73.   __free_hook = tr_freehook;
  74. }
  75.  
  76. static PTR
  77. DEFUN(tr_mallochook, (size), size_t size)
  78. {
  79.   PTR hdr;
  80.  
  81.   __malloc_hook = old_malloc_hook;
  82.   hdr = (PTR) malloc(size);
  83.   __malloc_hook = tr_mallochook;
  84.  
  85.   /* We could be printing a NULL here; that's OK */
  86.   fprintf (mallstream, "+ %08x %x\n", hdr, size);
  87.  
  88.   if (hdr == mallwatch)
  89.     tr_break();
  90.  
  91.   return hdr;
  92. }
  93.  
  94. static PTR
  95. DEFUN(tr_reallochook, (ptr, size), PTR ptr AND size_t size)
  96. {
  97.   PTR hdr;
  98.  
  99.   if (ptr == mallwatch)
  100.     tr_break();
  101.  
  102.   __free_hook = old_free_hook;
  103.   __malloc_hook = old_malloc_hook;
  104.   __realloc_hook = old_realloc_hook;
  105.   hdr = (PTR) realloc(ptr, size);
  106.   __free_hook = tr_freehook;
  107.   __malloc_hook = tr_mallochook;
  108.   __realloc_hook = tr_reallochook;
  109.   if (hdr == NULL) {
  110.     fprintf (mallstream, "! %08x %x\n", ptr, size);    /* Failed realloc */
  111.   } else {
  112.     fprintf (mallstream, "< %08x\n> %08x %x\n", ptr, hdr, size);
  113.   }
  114.  
  115.   if (hdr == mallwatch)
  116.     tr_break();
  117.  
  118.   return hdr;
  119. }
  120.  
  121. /* We enable tracing if either the environment variable MALLOC_TRACE
  122.    is set, or if the variable mallwatch has been patched to an address
  123.    that the debugging user wants us to stop on.  When patching mallwatch,
  124.    don't forget to set a breakpoint on tr_break!  */
  125.  
  126. void
  127. mtrace()
  128. {
  129.   char *mallfile;
  130.  
  131.   mallfile = getenv (mallenv);
  132.   if (mallfile || mallwatch) {
  133.     mallstream = fopen (mallfile? mallfile: "/dev/null", "w");
  134.     if (mallstream) {
  135.       /* Be sure it doesn't malloc its buffer! */
  136.       setbuf (mallstream, mallbuf);
  137.       fprintf (mallstream, "= Start\n");
  138.       old_free_hook = __free_hook;
  139.       __free_hook = tr_freehook;
  140.       old_malloc_hook = __malloc_hook;
  141.       __malloc_hook = tr_mallochook;
  142.       old_realloc_hook = __realloc_hook;
  143.       __realloc_hook = tr_reallochook;
  144.     }
  145.   }
  146. }
  147.